package com.edroid.autorunner;

import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.FilenameFilter;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Random;

import android.annotation.SuppressLint;
import android.app.AlertDialog;
import android.app.Dialog;
import android.app.DialogFragment;
import android.content.BroadcastReceiver;
import android.content.ClipData;
import android.content.ClipboardManager;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
import android.content.res.Resources;
import android.graphics.drawable.Drawable;
import android.net.ConnectivityManager;
import android.net.wifi.WifiManager;
import android.os.Bundle;
import android.os.Handler;
import android.os.Handler.Callback;
import android.os.Message;
import android.os.PowerManager;
import android.os.PowerManager.WakeLock;
import android.os.SystemClock;
import android.support.v4.os.EConstants;
import android.text.Editable;
import android.text.TextUtils;
import android.text.TextWatcher;
import android.view.ContextMenu;
import android.view.ContextMenu.ContextMenuInfo;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.SubMenu;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.view.WindowManager;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.AdapterView.OnItemLongClickListener;
import android.widget.AdapterView.OnItemSelectedListener;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.CompoundButton;
import android.widget.CompoundButton.OnCheckedChangeListener;
import android.widget.EditText;
import android.widget.ListView;
import android.widget.Spinner;
import android.widget.TextView;
import android.widget.Toast;

import com.edroid.apkhooker.R;
import com.edroid.apkhooker.db.ImeiDB;
import com.edroid.apkhooker.db.ModelDB;
import com.edroid.autorunner.StateFloatButton.State;
import com.edroid.autorunner.um.DayInfo;
import com.edroid.autorunner.um.UserDB;
import com.edroid.autorunner.um.UserInfo;
import com.edroid.autorunner.um.UserMaker;
import com.edroid.autorunner.um.UserManager;
import com.example.clone.CloneActivity;
import com.example.service.SystemServiceGetter;
import com.example.utils.FileUtils;
import com.example.utils.FileUtils.LineReaderCallback;
import com.example.utils.KvTool;
import com.example.utils.Logger;
import com.example.utils.NativeProcessScaner;
import com.example.utils.Shell;
import com.example.utils.TimeUtils;
import com.example.utils.Zmlib;

/**
 * 
 * @author yichou 2014-4-18 10:13:34
 *
 */
@SuppressLint("SdCardPath")
public class AutoRunActivity extends BaseDrawerActivity implements Callback,OnClickListener, OnItemClickListener,
		OnItemLongClickListener, OnCheckedChangeListener {
	public static final Logger log = Logger.create("AutoRunActivity");
	private static boolean normalExit;
	static final String[] SAVES = { "10%", "20%", "30%", "40%", "50%", "60%",
			"70%", "80%", "90%", "100%" };
	static final String[] OPS = { "随机", "移动", "联通", "电信" };
	
	public static String curRunningAppName;

	Context mContext;
	Handler mHandler,mTimeHandler;

	int curCount = 0;   
	int mToday = TimeUtils.getDayOfYearBase2014();

	// 以下几个初始值为默认值
	int maxNewCount = 900;
	int maxDayCount = 7;
	int runTime = 40;
	int repeatDay = -1;
	int percent = 40;
	int op = UserMaker.OP_ALL; // 默认随机
	int appTime = 60;
	long time_idle_start;

	static final int RUN_MODE_CYCLE = 1;
	static final int RUN_MODE_ONCE = 2;
	static final int RUN_MODE_NEW = 3;
	static final int RUN_MODE_REC_SCRIPT = 4;
	static final int RUN_MODE_RPT_DAY = 5;
	int runMode; //


	private PowerManager pm;
	private WakeLock lock;

	private EditText editNewMax, editTime, editDayMax, editChnnel;
	private EditText et_price,et_comment;
	private CheckBox checkBox1, checkBox2, checkBox4, checkBoxReOpen, checkBoxToDesktop, checkBoxToDesktop2;
	private CheckBox chk_walic, chk_force_rpt_20s, chk_resolution, chk_rpt_loop_mode, chk_useImeiDB;
	private TextView tvCount, tvPercent, tvSdkType;
	private Button circleButton;

	boolean enableInnerScript = true;
	boolean makeNewAfterFinish = true;
	boolean clearData = true;
	boolean reOpen = false;
	boolean toDesktop = false;
	boolean rpt_loop_mode = false;
	
	/**
	 * 刷量包包名
	 */
	private String app;
	private String channel, sdkType;
	private UserDB userDB;

	private ListView listView;
	private ArrayAdapter<String> listAdapter;
	private final ArrayList<String> listItems = new ArrayList<String>();
	private List<DayInfo> days;
	private int pressedIndex;

	final float[] percents = new float[40];

	final Random random = new Random();

	private int netFailTimes = 0;
	private long lastNetTestTime;

	private static boolean useWalic, isWalicRec, isWalicRunning;
	private static boolean force_rpt_20s;
	public static boolean useImeiDB;
	
	/**
	 * /data/data/com.edroid.apkhooker/files/walic
	 */
	private static String mWalicPath;
	/**
	 * /sdcard/apkhooker/walicRec/
	 */
	private static String mWalicRecordDir;

	//是否是WIFI状态，强制使用WIFI状态，强制使用移动网络状态
	private static boolean isRunningInWifiMode,forceWifiMode,forceMobieMode,hookResolution;
	
	private boolean isRunning;

	final StateFloatButton stateFloat = StateFloatButton.getInstance();

	Drawable icon;

	public static final String KEY_APP = "app";
	public static final String KEY_RUN_TYPE = "runType";
	public static final String RUN_TYPE_NORMAL = "normal";

	public void setState(State s) {
		stateFloat.setState(s);
	}

	static final DecimalFormat DECIMAL_FORMAT = new DecimalFormat("#.##");

	/**
	 * 生成一个 -i 到 i 之间的随机数，小数点后2位
	 */
	float randomRange_2(float i) {
		random.setSeed(System.currentTimeMillis());
		float ret = (random.nextBoolean() ? 1 : -1) * i * random.nextFloat();
		ret = Float.parseFloat(DECIMAL_FORMAT.format(ret));
		System.out.println(ret);

		return ret;
	}

	float randomRange(float i) {
		random.setSeed(System.currentTimeMillis());
		return (random.nextBoolean() ? 1 : -1) * i * random.nextFloat();
	}

	/**
	 * 生成 -5 到 5之间的随机数一个
	 */
	float randomRange() {
		return randomRange(5);
	}

	/**
	 * 检查天数
	 */
	void checkDayPass() {
		int i = TimeUtils.getDayOfYearBase2014();
		if (i != mToday) {
			// 初始化一些随机参数

			mToday = i;
		}
	}

	float round(float f) {
		return (int) (f * 100) / 100f;
	}

	/**
	 * 初始化留存率表
	 */
	void makePercents() {
		percents[1] = round(percent + randomRange()); // 1
		percents[2] = round(percents[1] - 10 + randomRange(5));// 2
		percents[3] = round(percents[2] + randomRange(5));// 3
		percents[4] = round(percents[3] + randomRange(5));// 3

		for (int i = 3; i < 14; i++) {
			percents[i] = round(percents[2] - 2 * (i - 2) + randomRange(4));
			if (percents[i] < 10) {
				percents[i] = round(10 + randomRange(2));
				sleep(10);
			}
		}

		for (int i = 14; i < 30; i++) {
			percents[i] = round(10.0f - 0.4f * (i - 14) + randomRange(3.6f));
		}
	}

	void showPercents() {
		StringBuilder sb = new StringBuilder(128);
		for (int i = 1; i < percents.length; i++) {
			sb.append(i).append('.').append(percents[i]).append('%')
					.append('\n');
		}

		tvPercent.setText(sb.toString());
	}

	void resetPercents() {
		makePercents();
		savePercents();
		showPercents();
	}

	void readPercents(String str) {
		String sp = "\n";
		if (str.indexOf(',') != -1)
			sp = ",";
		String[] ss = str.split(sp);
		int i = 1;
		for (String s : ss) {
			try {
				percents[i] = Float.parseFloat(s);
			} catch (Exception e) {
			}
			i++;
		}
	}

	void parsePercents(String str) {
		readPercents(str);
		savePercents();
		showPercents();
	}

	void readPercents() {
		String str = FileUtils.readFileToString(getFileStreamPath("percents"));
		if (str == null || str.length() == 0) {
			makePercents();
			savePercents();
		} else {
			readPercents(str);
		}

		showPercents();
	}

	void savePercents() {
		StringBuilder sb = new StringBuilder(128);
		for (int i = 1; i < percents.length; i++) {
			sb.append(percents[i]);

			if (i != percents.length - 1)
				sb.append('\n');
		}
		FileUtils.writeStringToFile(getFileStreamPath("percents"), sb.toString());
	}

	/**
	 * 获取留存率
	 */
	float getPercent(int day) {
		int i = TimeUtils.getDayOfYearBase2014() - day;
		if (i >= percents.length)
			return 0;

		return percents[i];
	}

	private void readDays() {
		long t0 = System.currentTimeMillis();
		days = userDB.queryDays(percent);

		for (DayInfo dayInfo : days) {
			float f = getPercent(dayInfo.day);

			if (dayInfo.count == 0)
				dayInfo.repeatFinished = true;
			else
				dayInfo.repeatFinished = ((dayInfo.repeat / (float) dayInfo.count) * 100 > f);
		}

		log.i("read all days use time: " + (System.currentTimeMillis() - t0));

		// 刷新列表
		listItems.clear();
		for (DayInfo day : days) {
			listItems.add(day.toString());
		}
		listAdapter.notifyDataSetChanged();
	}

	int toInt(String s) {
		try {
			return Integer.parseInt(s);
		} catch (Exception e) {
		}
		return 0;
	}

	private final BroadcastReceiver mPkgReceiver = new BroadcastReceiver() {

		@Override
		public void onReceive(final Context context, final Intent intent) {
			if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) {
				showLog("安装成功：" + intent.getData().getSchemeSpecificPart());
				if (isRunning) {
					// 应用安装成功，先启动3秒，再关闭它
					final String pkg = intent.getData().getSchemeSpecificPart();
					Intent startIntent = getPackageManager()
							.getLaunchIntentForPackage(pkg);
					if (startIntent != null) {
						startIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
						startIntent.addFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION);
						try{
							startActivity(startIntent);
						}catch(Exception e) {
							e.printStackTrace();
						}

						mHandler.postDelayed(new Runnable() {

							@Override
							public void run() {
								SystemServiceGetter.getPermissionService().forceStopPackage(pkg);
							}
						}, 3000);
					}

					recodePkg(intent.getData().getSchemeSpecificPart());
				}
			} else if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())) {
				showLog("卸载成功：" + intent.getData().getSchemeSpecificPart());
				log.e(intent.toString());
				log.e(intent.getExtras().toString());
//				06-02 17:23:57.208: E/AutoRunActivity(2921): 
//				Intent { act=android.intent.action.PACKAGE_REMOVED 
//						dat=package:cn.opda.a.phonoalbumshoushou 
//						flg=0x8000010 (has extras) }


			} else if (Intent.ACTION_SCREEN_ON.equals(intent.getAction())) {
				time_idle_start = System.currentTimeMillis();
				if (stateFloat.getCurState() == State.STA_SLEEP)
					stateFloat.setState(State.STA_IDLE);
				wifiOn();
				unLockScreen();
				time_idle_start = System.currentTimeMillis();
			} else if ("com.edroid.intent.action.runapk".equals(intent.getAction())) {
				/**
				 * apk 崩溃后发出此广播收到重启
				 */
				SystemClock.sleep(3000);
				stopAndrRunApk(false);
				
				showLog("异常重启！");
			}
		}
	};

	private void unregPkgReceiver() {
		unregisterReceiver(mPkgReceiver);
	}

	private void regPkgReceiver() {
		IntentFilter pkgFilter = new IntentFilter();
		pkgFilter.addDataScheme("package");
		pkgFilter.addAction(Intent.ACTION_PACKAGE_ADDED);
		pkgFilter.addAction(Intent.ACTION_PACKAGE_REMOVED);
		registerReceiver(mPkgReceiver, pkgFilter);

		IntentFilter filter2 = new IntentFilter();
		filter2.addAction(Intent.ACTION_SCREEN_ON);
		filter2.addAction("com.edroid.intent.action.runapk");
		registerReceiver(mPkgReceiver, filter2);
	}

	private void toast(Object object) {
		String string = "" + object;
		Toast.makeText(this, string, Toast.LENGTH_SHORT).show();
		log.e(string);
	}
	
	private void toastLong(Object object) {
		String string = "" + object;
		Toast.makeText(this, string, Toast.LENGTH_LONG).show();
		log.w(string);
	}
	/**
	 * 确保walic可用
	 */
	private void ensureWalicExists() {
		mWalicRecordDir = EConstants.ROOT_PATH + "/walicRec/";
		new File(mWalicRecordDir).mkdirs();//必需保证绝对存在！
		try {
			mWalicPath = Zmlib.releaseFile(this, "walic");
			Shell.runRootCmd("chmod 777 " + mWalicPath);
		} catch (IOException e) {
			toastLong("释放walic出错");
			e.printStackTrace();
		}
	}

	@SuppressWarnings("deprecation")
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState); //!!!
		
		log.e("onCreate " + savedInstanceState);
		
		ensureWalicExists();
		normalExit=false;//非正常退出
		try {
			ModelDB.init(this);
		} catch (IOException e1) {
			Zmlib.msgBoxOk(this, "机型数据库无法打开！", null);
			e1.printStackTrace();
		}
		try {
			ImeiDB.init(this);
		} catch (IOException e1) {
			Zmlib.msgBoxOk(this, "IMEI数据库无法打开！", null);
			e1.printStackTrace();
		}
		regPkgReceiver();

		mContext = this;
		mHandler = new Handler(this);
		mTimeHandler = new Handler(this);
		// 启动计时器
		mTimeHandler.post(timeRunnable);
		chk_walic = (CheckBox) findViewById(R.id.chk_useWalic);
		chk_walic.setOnCheckedChangeListener(this);
		chk_force_rpt_20s = (CheckBox) findViewById(R.id.chk_force_rpt_20s);
		chk_rpt_loop_mode = (CheckBox) findViewById(R.id.chk_rpt_loop_mode);
		chk_useImeiDB = (CheckBox) findViewById(R.id.chk_useImeiDB);
		chk_force_rpt_20s.setOnCheckedChangeListener(this);
		checkBox1 = (CheckBox) findViewById(R.id.checkBox1);
		checkBox2 = (CheckBox) findViewById(R.id.checkBox2);
		checkBox4 = (CheckBox) findViewById(R.id.checkBox4);
		
		checkBoxReOpen = (CheckBox) findViewById(R.id.checkBoxReOpen);
        checkBoxReOpen.setOnCheckedChangeListener(this);
		
        checkBoxToDesktop = (CheckBox) findViewById(R.id.checkToDesktop);
		checkBoxToDesktop.setOnCheckedChangeListener(this);
        
        checkBoxToDesktop2 = (CheckBox)findViewById(R.id.checkToDesktop2);
        chk_resolution = (CheckBox)findViewById(R.id.chk_resolution);

		tvCount = (TextView) findViewById(R.id.tvCount);
		tvPercent = (TextView) findViewById(R.id.tvPercent);
		tvSdkType = (TextView) findViewById(R.id.tvSdkType);

		findViewById(R.id.button1).setOnClickListener(this);
		circleButton = (Button) findViewById(R.id.button3);
		circleButton.setOnClickListener(this);
		findViewById(R.id.button4).setOnClickListener(this);
		findViewById(R.id.button5).setOnClickListener(this);
		findViewById(R.id.btnReadChannel).setOnClickListener(this);
		findViewById(R.id.btnParseChannel).setOnClickListener(this);
		findViewById(R.id.btnReSetP).setOnClickListener(this);
		findViewById(R.id.btnEditP).setOnClickListener(this);
		findViewById(R.id.btnToApp).setOnClickListener(this);
		editChnnel = (EditText) findViewById(R.id.editText4);
		editNewMax = (EditText) findViewById(R.id.editText1);
		editTime = (EditText) findViewById(R.id.editText2);
		editDayMax = (EditText) findViewById(R.id.editText3);
		et_price = (EditText) findViewById(R.id.et_price);
		et_comment = (EditText) findViewById(R.id.et_comment);

		// 读取数据
		app = getIntent().getStringExtra(KEY_APP);
		setSubTitle2(app);

		// 读取应用图标之类
		try {
			PackageManager pm = getPackageManager();

			ApplicationInfo info = pm.getApplicationInfo(app, 0);

			CharSequence label = pm.getApplicationLabel(info);
			setTitle2(label != null ? label : "null");
			
			curRunningAppName = label.toString();

			icon = pm.getApplicationIcon(info);
			setIcon2(icon);
		} catch (Exception e) {
			e.printStackTrace();
		}

		readParams();//读取设置参数
		
		chk_resolution.setChecked(hookResolution);
		chk_walic.setChecked(useWalic);
		chk_force_rpt_20s.setChecked(force_rpt_20s);
		chk_rpt_loop_mode.setChecked(rpt_loop_mode);
		chk_useImeiDB.setChecked(useImeiDB);
		checkBoxToDesktop.setChecked(toDesktop);
		checkBoxReOpen.setChecked(reOpen);
		tvSdkType.setText(sdkType);
		editDayMax.setText(String.valueOf(maxDayCount));
		editTime.setText(String.valueOf(runTime));
		editNewMax.setText(String.valueOf(maxNewCount));
		// 读取渠道号
		{
			if (channel == null) { // 尝试解析
				channel = parseChannel();
			}
			if (channel == null) {
				channel = "abc";
			}
			channel = channel.trim(); //有些解析出来的渠道号字符串有问题所以这里做下处理
			editChnnel.setText(channel);
		}
		userDB = UserDB.create(this, app + "_" + channel);

		// 留存率 spinner
		{
			Spinner spinner = (Spinner) findViewById(R.id.spinner1);
			ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,
					android.R.layout.simple_spinner_dropdown_item, SAVES);
			adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
			spinner.setAdapter(adapter);

			int i = percent / 10 - 1;
			spinner.setSelection(i);
			readPercents();

			spinner.setOnItemSelectedListener(new OnItemSelectedListener() {

				@Override
				public void onItemSelected(AdapterView<?> parent, View view,
						int position, long id) {
					String str = SAVES[position];
					percent = toInt(str.substring(0, str.length() - 1));

					resetPercents();
					readDays();
				}

				@Override
				public void onNothingSelected(AdapterView<?> parent) {
				}
			});
		}

		// 运营商 spinner
		{
			UserMaker.setDefOP(op);

			Spinner spinner = (Spinner) findViewById(R.id.spinnerOP);
			ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,
					android.R.layout.simple_spinner_dropdown_item, OPS);
			adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
			spinner.setAdapter(adapter);
			spinner.setSelection(op);
			spinner.setOnItemSelectedListener(new OnItemSelectedListener() {

				@Override
				public void onItemSelected(AdapterView<?> parent, View view,
						int position, long id) {
					op = position;
					UserMaker.setDefOP(op);
				}

				@Override
				public void onNothingSelected(AdapterView<?> parent) {
				}
			});
		}

		editDayMax.addTextChangedListener(new TextWatcher() {
			@Override
			public void onTextChanged(CharSequence s, int start, int before,
					int count) {
			}

			@Override
			public void beforeTextChanged(CharSequence s, int start, int count,
					int after) {
			}

			@Override
			public void afterTextChanged(Editable s) {
				maxDayCount = toInt(s.toString());
				readDays();
			}
		});


		StateFloatButton.getInstance().onActivityCreate(this);
		StateFloatButton.getInstance()
				.setChannelText(editChnnel.getText().toString());
		setState(State.STA_STOP);

		checkDayPass();

		{
			pm = (PowerManager) getSystemService(Context.POWER_SERVICE);
			lock = pm.newWakeLock(PowerManager.SCREEN_DIM_WAKE_LOCK
					| PowerManager.ON_AFTER_RELEASE, "your sister");
		}

		getWindow().addFlags(WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD);

		Common.killGosts(app);

		if(getIntent().getBooleanExtra("resumeStart", false)) {
			onClick(circleButton);
		}
		
		setStartDrawerWidth(0.8f); //侧滑列表宽度，占屏幕宽度比例
	}

	protected AutoRunActivity getActivity() {
		return this;
	}

	/**
	 * 从 mainfest 解析渠道号
	 */
	String parseChannel() {
		tvSdkType.setText(null);

		String channel = null;

		do {
			try {
				Resources res = getPackageManager().getResourcesForApplication(
						app);
				InputStream is = res.getAssets().open("cid.dat");
				channel = FileUtils.readStreamToString(is);
				tvSdkType.setText("360");

				res.getAssets().close();
			} catch (Exception e) {
			}

			try {
				Resources res = getPackageManager().getResourcesForApplication(
						app);
				InputStream is = res.getAssets().open("conf");
				channel = FileUtils.readStreamToString(is);
				if (!TextUtils.isEmpty(channel)) {
					channel = channel.split("=")[1].trim();

					tvSdkType.setText("360");
				}

				res.getAssets().close();
			} catch (Exception e) {
			}

			if (channel != null)
				break;

			try {
				Bundle metaData = getPackageManager().getApplicationInfo(app,
						PackageManager.GET_META_DATA).metaData;
				if (metaData != null) {
					for (String key : metaData.keySet()) {
						String tmp = key.toUpperCase(getResources()
								.getConfiguration().locale);

						if (tmp.contains("CHANNEL") || tmp.contains("CHN")) {
							channel = metaData.get(key).toString();

							if (tmp.contains("UMENG")) {
								tvSdkType.setText("友盟");
							} else if (tmp.contains("BAIDU")) {
								tvSdkType.setText("百度");
							} else {
								tvSdkType.setText(tmp);
							}

							break;
						}
					}
				}
			} catch (NameNotFoundException e) {
				log.w("Mainfest 解析渠道失败！");
			}

			if (channel != null)
				break;

		} while (false);

		return channel;
	}

	@Override
	public void onPanelOpened() {
		readDays();

		final String title = TimeUtils.getNow("M.d") + " 序号:"
				+ TimeUtils.getDayOfYearBase2014();
		setDrawerTitle(title);
	}

	@Override
	protected void onSaveInstanceState(Bundle outState) {
		super.onSaveInstanceState(outState);

		outState.putInt("runMode", runMode);

		log.e("onSaveInstanceState ");
	}

	@Override
	protected void onRestoreInstanceState(Bundle savedInstanceState) {
		super.onRestoreInstanceState(savedInstanceState);

		log.e("onRestoreInstanceState " + savedInstanceState);

		Common.killGosts(app);

		runMode = savedInstanceState.getInt("runMode");
		startRunByMode(runMode);
	}

	private void killWalic() {
		toast("isWalicRunning:"+isWalicRunning);
		if (useWalic && isWalicRunning) {
			// 在运行时不允许返回到AutoRunActivity，必须杀死walic
			toast("强制结束walic");
			Shell.kill("walic");
		}
	}

	@Override
	protected void onResume() {
		super.onResume();

		log.e("onResume ");
		killWalic();

		time_idle_start = System.currentTimeMillis();
		chk_walic.setChecked(useWalic);
		chk_force_rpt_20s.setChecked(force_rpt_20s);
	}

	@Override
	protected void onPause() {
		super.onPause();
		log.e("onPause ");
	}

	@Override
	public void onBackPressed() {
		super.onBackPressed();
		normalExit = true;//正常退出
	}

	@Override
	protected void onDestroy() {
		super.onDestroy();

		curRunningAppName = null;
		getWindow().clearFlags(WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD);

		log.e("onDestroy");

		stop("onDestroy");
		unregPkgReceiver();
		mHandler.removeCallbacksAndMessages(null);
		mTimeHandler.removeCallbacksAndMessages(null);
		saveParams();
		ModelDB.close();
		ImeiDB.close();
		userDB.close();
		if(!normalExit) {//非正常退出
			stateFloat.startWarn();
			stateFloat.setState(State.STA_ERR2);
			stateFloat.setMsgText("异常onDestroy");
			new Thread() {
				public void run() {
					try {
						Thread.sleep(5000);
						Intent intent = getIntent();
						intent.putExtra("resumeStart", true);
						startActivity(intent);
					} catch (Exception exception) {
						exception.printStackTrace();
					}
				};
			}.start();
		}
	}

	/**
	 * 打开对应渠道的数据库
	 */
	private void readChannelDB() {
		String tmp = editChnnel.getText().toString();
		if (!tmp.equals(channel)) {
			channel = tmp;
			if (userDB != null)
				userDB.close();
			userDB = UserDB.create(this, app + "_" + channel);
			stateFloat.setChannelText(channel);

			Toast.makeText(this, "读取成功", Toast.LENGTH_SHORT).show();
			saveParams();
		}
	}

	@Override
	public void onItemClick(AdapterView<?> parent, View view, int position,
			long id) {
		runMode = RUN_MODE_RPT_DAY;
		repeatDay = days.get(position).day;
		start();
	}

	@Override
	public boolean onItemLongClick(AdapterView<?> parent, View view,
			int position, long id) {
		pressedIndex = position;
		return false;
	}

	private void startRunByMode(int mode) {
		runMode = mode;
		start();
	}

	@Override
	public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
		int id = buttonView.getId();

		if (id == R.id.checkBoxReOpen) {
			reOpen = isChecked;
		} else if (id == R.id.checkToDesktop) {
			toDesktop = isChecked;
		} else if (id == R.id.chk_useWalic) {
			useWalic = isChecked;
		}
		switch (id) {
		case R.id.chk_force_rpt_20s:
			force_rpt_20s = isChecked;
			break;
		case R.id.chk_useImeiDB:
			useImeiDB = isChecked;
		default:
			break;
		}
	}

	@Override
	public void onClick(View v) {
		switch (v.getId()) {
		case R.id.button3: { // 循环
			runMode = RUN_MODE_CYCLE;
			start();
			break;
		}
		case R.id.button1: { // 停止循环
			stop("停止循环");
			stopApk();
			stateFloat.setTime(0);
			mHandler.removeCallbacksAndMessages(null);
			break;
		}
		case R.id.button4: { // 运行一次
			runMode = RUN_MODE_ONCE;
			start();
			break;
		}

		case R.id.btnReadChannel: { // 读渠道数据
			readChannelDB();
			break;
		}

		case R.id.btnParseChannel: { // 读渠道数据
			String s = parseChannel();
			if (s != null) {
				editChnnel.setText(s);
				readChannelDB();
			}
			break;
		}

		case R.id.button5: { // 运行新增用户
			runMode = RUN_MODE_NEW;
			start();
			break;
		}

		case R.id.btnEditP: {
			showEditorDialog();
			break;
		}

		case R.id.btnReSetP: {
			resetPercents();
			break;
		}
		
		case R.id.btnToApp: {
			runApk();
			break;
		}

		default:
			break;
		}
	}

	@Override
	public void onCreateContextMenu(ContextMenu menu, View v,
			ContextMenuInfo menuInfo) {
		if (v == listView) {
			menu.add(1, 1, 1, "重置留存");
			return;
		}

		super.onCreateContextMenu(menu, v, menuInfo);
	}

	@Override
	public boolean onContextItemSelected(MenuItem item) {
		if (item.getGroupId() == 1) {
			switch (item.getItemId()) {
			case 1:
				userDB.resetRepeatDay(days.get(pressedIndex).day);
				readDays();
				break;

			default:
				return false;
			}

			return true;
		}

		return super.onContextItemSelected(item);
	}

	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		SubMenu subMenu = menu.addSubMenu(0, 0, 1, "录制脚本");
		subMenu.add(0, 1, 0, "录制wifi");
		subMenu.add(0, 10, 0, "录制手机网");

		menu.add(0, 2, 2, "参数设置");
		menu.add(0, 3, 3, "保存本页参数");
		menu.add(0, 4, 4, "关闭屏幕");
		menu.add(0, 5, 5, "克隆");
		menu.add(0, 6, 6, "编辑common.txt");

		subMenu = menu.addSubMenu(0, 0, 7, "walic录制");
		subMenu.add(0, 7, 8, "录制wifi");
		subMenu.add(0, 9, 9, "录制手机网");

//		menu.add(0, 8, 10, "启用walic").setCheckable(true).setChecked(useWalic);
		menu.add(0, 1234, 1234, "测试");
		// 添加菜单时下一个菜单ID 11

		return true;
	}
	
	@Override
	public boolean onOptionsItemSelected(MenuItem item) {
		if (item.getItemId() == 2) {
			SettingsDialog.show(getFragmentManager());
			return true;
		} else if (item.getItemId() == 3) {
			saveParams();
			return true;
		} else if (item.getItemId() == 4) {
			SystemServiceGetter.getPermissionService().deviceSleep(SystemClock.uptimeMillis());
		}
		switch (item.getItemId()) {
		case 1:// 录制wifi
			forceWifiMode = true;
			startRunByMode(RUN_MODE_REC_SCRIPT);
			break;
			
		case 10:// 录制手机网
			forceMobieMode = true;
			startRunByMode(RUN_MODE_REC_SCRIPT);
			break;
			
		case 7:// walic录制wifi
			forceWifiMode = true;
			walicRecord(item);
			break;
			
		case 9: // walic录制手机网络
			forceMobieMode = true;
			walicRecord(item);
			break;
			
		case 8:// use walic
			useWalic = !useWalic;
			item.setChecked(useWalic);
			break;
		case 5://clone
			startClone();
			break;
		case 6:
			editCommon_txt();
			break;
		case 1234:
			break;
		default:
			return super.onOptionsItemSelected(item);
		}
		return true;
	}

	/**
	 * 编辑common.txt脚本文件，在UserManager中调用，大多数情况下是用来删除sdcard文件夹
	 */
	private void editCommon_txt() {
		AlertDialog.Builder dlg = new AlertDialog.Builder(this);
		final EditText et = new EditText(this);
		final File file = new File(EConstants.COMMON_TXT);
		String content = null;
		if(file.exists()) {
			content = FileUtils.readFileToString(file);
		} else {
			content = "#0 rmdir xxx";
		}
		et.setText(content);
		
		dlg.setTitle("编辑:").setView(et)
		.setPositiveButton("保存", new DialogInterface.OnClickListener() {
			@Override
			public void onClick(DialogInterface dialog, int which) {
				String content = et.getText().toString();
				FileWriter fw = null;
				try {
					FileUtils.checkParentPath(file);
					fw = new FileWriter(file);
					fw.write(content);
					fw.close();
				}catch(Exception e) {
					
				}finally {
					try {
						fw.close();
					} catch (IOException e) {
					}
				}
			}
		}).setNegativeButton("取消", null)
		.create().show();
	}

	private Map<String, String> getClonePaths() {
		Map<String, String> map = new LinkedHashMap<String, String>();
		map.put("运行参数", getRunConfigPath());
		map.put("common.txt", EConstants.COMMON_TXT);
		map.put("wifi脚本", UserManager.getScriptPath_w(app));
		map.put("手机网脚本", UserManager.getScriptPath_m(app));
		map.put("walic wifi", getWalicRecPath_w());
		map.put("walic手机网", getWalicRecPath_m());
		map.put("数据库", userDB.getDBpath());
		return map;
	}
	private void startClone() {
		CloneActivity.setData(getClonePaths());
		startActivity(new Intent(this, CloneActivity.class));
		normalExit=true;
		finish();//！！！让克隆之后有机会刷新参数
	}
	private void walicRecord(MenuItem item) {
		useWalic = true;
		isWalicRec = true;
		item.setChecked(useWalic);
		startRunByMode(RUN_MODE_REC_SCRIPT);
	}

	@Override
	public boolean handleMessage(Message msg) {
		switch (msg.what) {
		case 10:
			toast(msg.obj);
			break;
		case 20:
			toastLong(msg.obj);
			break;
		default:
			return false;
		}

		return true;
	}

	void stop(String reason) {
		curCount = 0;
		isRunning = false;
		tvCount.setText(String.valueOf(curCount));
		stateFloat.setCountText(curCount);
		
		StateFloatButton.getInstance().stopWarn();
		setState(State.STA_STOP);

		if (lock.isHeld()) {
			lock.release();
		}
		String msg = "stop: " + reason;
		stateFloat.setMsgText(msg);
	}

	// void pause() {
	// isRunning = false;
	// }

	void readParams() {
//		SharedPreferences sp = getSharedPreferences("saved_params", 0);
		KvTool sp = new KvTool(getRunConfigPath());
		maxNewCount = sp.getInt("maxNewCount", maxNewCount);
		runTime = sp.getInt("runTime", runTime);
		appTime = sp.getInt("appTime", appTime);
		maxDayCount = sp.getInt("maxDayCount", maxDayCount);
		// appChnnel = sp.getString(app, app+"_abc"); //注意 默认值
		String s = sp.getString(app, null);
		if (s != null && s.startsWith(app)) {
			channel = s.substring(app.length() + 1);
		} else {
			channel = s;
		}
		useWalic = sp.getBoolean("useWalic", false);
		force_rpt_20s = sp.getBoolean("force_rpt_20s", false);
		rpt_loop_mode = sp.getBoolean("rpt_loop_mode", false);
		useImeiDB = sp.getBoolean("useImeiDB", false);
		UserMaker.currentImeiIndex = sp.getInt("currentImeiIndex", 0);
		sdkType = sp.getString("sdkType", null);
		percent = sp.getInt("percent", percent);
		op = sp.getInt("op", op);
		reOpen = sp.getBoolean("reOpen", false);
		toDesktop = sp.getBoolean("toDesktop", false);
		hookResolution = sp.getBoolean("hookResolution", false);
		et_comment.setText(sp.getString("et_comment", "a"));
		et_price.setText(sp.getString("et_price", "1.0"));
	}
	
	public String getRunConfigPath() {
//		return "/data/data/com.edroid.apkhooker/shared_prefs/saved_params.xml";
		return EConstants.ROOT_PATH + "/config.xml";
	}
	
	void saveParams() {
//		SharedPreferences sp = getSharedPreferences("saved_params", 0);
		KvTool sp = new KvTool(getRunConfigPath());
		sp.putInt("maxNewCount", toInt(editNewMax.getText().toString()))
				.putInt("runTime", toInt(editTime.getText().toString()))
				.putInt("maxDayCount", toInt(editDayMax.getText().toString()))
				.putString("sdkType", tvSdkType.getText().toString())
				.putBoolean("reOpen", checkBoxReOpen.isChecked())
				.putBoolean("toDesktop", checkBoxToDesktop.isChecked())
				.putBoolean("useWalic", chk_walic.isChecked())
				.putBoolean("force_rpt_20s", chk_force_rpt_20s.isChecked())
				.putBoolean("useImeiDB", chk_useImeiDB.isChecked())
				.putInt("currentImeiIndex",UserMaker.currentImeiIndex)
				.putBoolean("rpt_loop_mode", chk_rpt_loop_mode.isChecked())
				.putBoolean("hookResolution", chk_resolution.isChecked())
				.putString(app, channel).putInt("percent", percent)
				.putInt("op", op).putString("et_comment", et_comment.getText().toString())
				.putString("et_price", et_price.getText().toString())
				.commit();
	}
	String user; 

	void start() {
		if (isRunning) {
			showLog("已经运行，先停止");
			return;
		}
		user = NativeProcessScaner.getUserName(app);
		if (useWalic) { // 使用walic时不能开启内部脚本、自动返回桌面和二次启动待以后完善，现在先禁止
			checkBox1.setChecked(false);// 关闭脚本
			checkBoxReOpen.setChecked(false);// 禁止二次启动
			checkBoxToDesktop.setChecked(false);// 禁止返回桌面
			chk_force_rpt_20s.setChecked(false);
		}

		mHandler.removeCallbacksAndMessages(null);

		if (!isWifiOn())
			wifiOn();

		maxNewCount = toInt(editNewMax.getText().toString());
		if (maxNewCount > 100)
			maxNewCount += (int) randomRange(80);
		runTime = toInt(editTime.getText().toString());


		enableInnerScript = checkBox1.isChecked();
		makeNewAfterFinish = checkBox2.isChecked();
		clearData = checkBox4.isChecked();
		reOpen = checkBoxReOpen.isChecked();
		toDesktop = checkBoxToDesktop.isChecked();
		hookResolution = chk_resolution.isChecked();
		rpt_loop_mode = chk_rpt_loop_mode.isChecked();
		useImeiDB = chk_useImeiDB.isChecked();

		StateFloatButton.getInstance().setStateText("正在运行");
		StateFloatButton.getInstance().setBg(R.drawable.btn_bg_normal);

		isRunning = true;

		start2();

		saveParams();
	}

	void reStart(String appName) {
		if (!isRunning || isFinishing())
			return;

		final String msg = appName + " 第 " + (curCount) + " 次重启！";
		showLog(msg);

		mHandler.postDelayed(new Runnable() {

			@Override
			public void run() {
				if (!isRunning || isFinishing())
					return;

				start2();
			}
		}, 3000);
	}

	private void showLog(String msg) {
		log.i(msg);
		if (mContext != null)
			Toast.makeText(mContext, msg, Toast.LENGTH_SHORT).show();
	}

	boolean isRepeatEd(DayInfo dayInfo) {
		return (dayInfo == null || dayInfo.repeatFinished || dayInfo.count == 0);
	}

	/**
	 * 从列表查指定某天数据
	 */
	DayInfo getDay(List<DayInfo> list, int day) {
		for (int i = 0; i < list.size(); i++) {
			if (list.get(i).day == day)
				return list.get(i);
		}
		return null;
	}

	void lockScreen() {
		getWindow().clearFlags(WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD);

		SystemServiceGetter.getPermissionService().deviceSleep(SystemClock.uptimeMillis());
	}

	void unLockScreen() {
		SystemServiceGetter.getPermissionService().deviceWakeUp(SystemClock.uptimeMillis());

		getWindow().addFlags(WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD);
	}

	private UserInfo getUserInfo() {
		UserInfo userInfo = null;
		boolean newUser = false;

		if (runMode == RUN_MODE_CYCLE) // 自动留存
		{
			int day = -1;
			final int cur = TimeUtils.getDayOfYearBase2014();

			// 包含初始化留存数据功能
			readDays();

			List<DayInfo> list = days;

			final int N = list.size();
			if (N > 0) {
				DayInfo dstDayInfo = null;

				dstDayInfo = getDay(list, cur - 1); // 次日

				if (dstDayInfo == null || isRepeatEd(dstDayInfo)) // 7日
					dstDayInfo = getDay(list, cur - maxDayCount);

				if (dstDayInfo == null || isRepeatEd(dstDayInfo)) { // 7日内
					for (int i = 0; i < N; i++) { // 从第一天开始往后遍历，这种算法可能会丢掉排在后面的天，符合现实
						DayInfo tmpDayInfo = list.get(i);

						if (tmpDayInfo.day == cur)
							continue;

						if (cur - tmpDayInfo.day <= maxDayCount) {
							if (!isRepeatEd(tmpDayInfo)) { // 如果没重复完就重复这天
								dstDayInfo = tmpDayInfo;
								break;
							}
						}
					}
				}

				if (dstDayInfo == null || isRepeatEd(dstDayInfo)) // 14日
					dstDayInfo = getDay(list, cur - 14);
				if (dstDayInfo == null || isRepeatEd(dstDayInfo)) // 14日
					dstDayInfo = getDay(list, cur - 15);
				if (dstDayInfo == null || isRepeatEd(dstDayInfo)) // 14日
					dstDayInfo = getDay(list, cur - 29);
				if (dstDayInfo == null || isRepeatEd(dstDayInfo)) // 30日
					dstDayInfo = getDay(list, cur - 30);

				if (dstDayInfo != null && !isRepeatEd(dstDayInfo)) {
					day = dstDayInfo.day;
					showLog("从这天开始：" + dstDayInfo);
				} else { // 留存完毕
					day = -1;
					showLog("留存完毕！");
				}
			}

			// 如果到了晚上 10 点还在做留存，那么先进行新增
			if (day != -1 && TimeUtils.getHourOfDay() < 22) { // 10点之前 刷留存
				userInfo = userDB.getUserInfo(day, rpt_loop_mode);
				setState(State.STA_OLD);
			} else if (makeNewAfterFinish) {
				newUser = true;
			} else {
				stop("所有留存完毕！");
				setState(State.STA_FINISH);
				userInfo = UserMaker.getOriginalUser();
			}
		} else if (runMode == RUN_MODE_RPT_DAY) { // 刷单天留存
			readDays();

			DayInfo dstDayInfo = getDay(days, repeatDay);

			if (dstDayInfo != null && !isRepeatEd(dstDayInfo)) {
				showLog("留存日：" + dstDayInfo);

				userInfo = userDB.getUserInfo(repeatDay, rpt_loop_mode);

				setState(State.STA_OLD);
			} else {
				stop("单日留存完毕！");
			}
		} else {
			newUser = true;
		}

		if (newUser) {
			userInfo = userDB.createInfo();
			setState(State.STA_NEW);

			if (userInfo.index > maxNewCount) {
				stop("新增用户完毕！");
				setState(State.STA_FINISH);
			}

		} else if (userInfo != null) {
			// ??? 随机参数
			UserMaker.resetRandom(userInfo);
		}

		// 保存手机号到剪切板
		{
			ClipboardManager cm = (ClipboardManager) getSystemService(CLIPBOARD_SERVICE);
			cm.setPrimaryClip(ClipData.newPlainText(null, userInfo.num));
		}


		log.i("userinfo：" + userInfo.toString());

		return userInfo;
	}

	private void writeUser(KvTool kv) {
		UserInfo userInfo = getUserInfo();
		userInfo.save(kv);
		try{
			SystemServiceGetter.getSystemService().putString("imei", userInfo.imei);
			SystemServiceGetter.getSystemService().putString("imsi", userInfo.imsi);
			SystemServiceGetter.getSystemService().putString("num", userInfo.num);
	//		SystemServiceGetter.getSystemService().putString("icc", userInfo.num);
		}catch(Exception e){
			e.printStackTrace();
		}
	}

	void sleep(long time) {
		try {
			Thread.sleep(time);
		} catch (Exception e) {
		}
	}

	void netTestRun() {
		// 5分钟之后重置
		if (System.currentTimeMillis() - lastNetTestTime > 5 * 60 * 1000) {
			netFailTimes = 0;
		}

		HttpURLConnection conn = null;
		lastNetTestTime = System.currentTimeMillis();

		try {
			URL url = new URL("http://m.baidu.com");
			conn = (HttpURLConnection) url.openConnection();
			conn.getResponseCode();
			netFailTimes = 0; // 成功
		} catch (Exception e) {
			netFailTimes++;
			log.e("网络连接测试失败！");
			e.printStackTrace();
		} finally {
			if (conn != null)
				conn.disconnect();
		}
	}

	void netTest() {
		new Thread(new Runnable() {

			@Override
			public void run() {
				netTestRun();
			}
		}).start();
	}

	boolean isWifiOn() {
		WifiManager wifiManager = (WifiManager) mContext
				.getSystemService(Context.WIFI_SERVICE);
		return wifiManager.isWifiEnabled();
	}

	void wifiOn() {
		WifiManager wifiManager = (WifiManager) mContext
				.getSystemService(Context.WIFI_SERVICE);
		wifiManager.setWifiEnabled(true);
	}

	void wifiOff() {
		WifiManager wifiManager = (WifiManager) mContext
				.getSystemService(Context.WIFI_SERVICE);
		wifiManager.setWifiEnabled(false);
	}

	void wifiReset() {
		WifiManager wifiManager = (WifiManager) mContext
				.getSystemService(Context.WIFI_SERVICE);
		wifiManager.setWifiEnabled(false);

		sleep(1000);

		wifiManager.setWifiEnabled(true);
		wifiManager.startScan();

		Toast.makeText(mContext, "重启wifi", Toast.LENGTH_SHORT).show();
	}
	
	// 拼接录制文件名
	public String getWalicRecPath_w() {
		return mWalicRecordDir + app + "_w";
	}
	
	public String getWalicRecPath_m() {
		return  mWalicRecordDir + app + "_m";
	}

	/**
	 * 拼接带文件名的walic命令
	 * 
	 * @return
	 */
	private String getWalicCmd() {
		String wifi = getWalicRecPath_w();
		String mobi = getWalicRecPath_m();
		String ret_wifi = mWalicPath + " " + wifi;
		String ret_mobi = mWalicPath + " " + mobi;
		if (isWalicRec) {
			return isRunningInWifiMode ? ret_wifi : ret_mobi;
		} else {
			// 播放模式下，尽可能提供可运行的脚本文件
			if (isRunningInWifiMode) {
				return new File(wifi).exists() ? ret_wifi : ret_mobi;
			} else {
				return new File(mobi).exists() ? ret_mobi : ret_wifi;
			}
		}
	}
	/**
	 * walic录制/播放 控制
	 */
	private void doWalic() {
		if (isRunning && useWalic) {
			if (isWalicRec) {
				new Thread() {
					private String cmd;

					@Override
					public void run() {
						cmd = getWalicCmd() + " " + runTime;
						isWalicRec = false;
						Message msg = new Message();
						msg.what = 10;
						msg.obj = "开始录制:" + cmd;
						mHandler.sendMessage(msg);
						msg = new Message();//msg不能重复使用
						msg.what = 10;
						
						isWalicRunning = true;
						switch (Shell.runRootCmd2(cmd)) {
						case 0:
							msg.obj = "录制完毕";
							mHandler.sendMessage(msg);
							break;
						case 137:
							msg.obj = "强制结束";
							mHandler.sendMessage(msg);
							break;
						default:
							msg.obj = "异常终止";
							mHandler.sendMessage(msg);
							break;
						}
						isWalicRunning = false;
					}
				}.start();
			} else {
				new Thread() {
					private String cmd;

					@Override
					public void run() {
						cmd = getWalicCmd();
						Message msg = new Message();
						msg.what = 10;
						msg.obj = "开始播放:" + cmd;
						mHandler.sendMessage(msg);
						msg = new Message();//msg不能重复使用
						msg.what = 10;

						isWalicRunning = true;
						switch (Shell.runRootCmd2(cmd)) {
						case 0:
							msg.obj = "播放完毕";
							mHandler.sendMessage(msg);
							break;
						case 137:
							msg.obj = "强制结束";
							mHandler.sendMessage(msg);
							break;
						default:
							msg.obj = "异常终止";
							mHandler.sendMessage(msg);
							break;
						}
						isWalicRunning = false;
					}
				}.start();
			}
		}
	}

	private void runApk() {
		try {
			Intent intent = getPackageManager().getLaunchIntentForPackage(app);
			intent.addFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION);
			getApplicationContext().startActivity(intent);
			doWalic();
		} catch (Exception e) {
			showLog("启动失败！" + e.getMessage());
		}
	}

	private void stopAndrRunApk() {
		stopAndrRunApk(clearData);
	}
	private void stopApk(){
		SystemServiceGetter.getPermissionService().forceStopPackage(app);
		//TODO
		if(app.equals("com.qihoo.appstore")){
			SystemServiceGetter.getPermissionService().forceStopPackage("com.qihoo.daemon");
//			Shell.kill("qh_rt_service");
//			Shell.kill("sservice");
//			Shell.kill("CoreDaemon");
		}else if(app.equals("cn.opda.a.phonoalbumshoushou")){//百度卫士
			//百度卫士
			Shell.kill("/data/data/cn.opda.a.phonoalbumshoushou/files/bp10");
		}
		new Thread(){
			public void run() {
				if(user!=null){
					List<String> lines = Shell.runCmdAndGetResult("ps");
					for(String l : lines){
						if(l.startsWith(user)){
							String[] ss = l.split("\\s+");
							String pid = ss[1];
							Shell.runRootCmd2("kill -9 "+pid);
						}
					}
				}
			};
		}.start();
	}
	/**
	 * 重新启动 apk
	 * 
	 * @param clear
	 *            时候清除应用数据
	 */
	private void stopAndrRunApk(boolean clear) {
		stopApk();
		
		
		
		if (clear) {
			SystemServiceGetter.getPermissionService().clearData(app);
			SystemServiceGetter.getPermissionService().clearCache(app);
		}
		
		mHandler.postDelayed(new Runnable() {
			
			@Override
			public void run() {
				runApk();
			}
		}, 1000);
	}

	public static KvTool getDataPreferences(String pkg) {
		File file = new File(EConstants.ROOT_PATH, "/apps/" + pkg + ".ekv");
		FileUtils.checkParentPath(file);
		UserManager.log.d("data file=" + file);

		return new KvTool(file);
	}

	/**
	 * 记录运行过程中安装的包，下次启动删除
	 * 
	 * @param pkg
	 */
	public static synchronized void recodePkg(String pkg) {
		File file = new File(EConstants.ROOT_PATH,
				EConstants.FILE_NAME_PKG_RECODE);
		String str = FileUtils.readFileToString(file);

		if (str == null || str.length() == 0)
			str = "com.fuckqq"; // 为后面分割简单起见，加一个不存在的包名

		str += ',' + pkg;

		FileUtils.writeStringToFile(file, str);
	}

	/**
	 * 删除已安装的包
	 */
	private void checkInstalledPkgs() {
		File file = new File(EConstants.ROOT_PATH,
				EConstants.FILE_NAME_PKG_RECODE);
		String str = FileUtils.readFileToString(file);
		if (str != null && str.length() > 0) {
			String[] pkgs = str.split(",");
			for (String pkg : pkgs) {
				if (pkg.equals(app))
					continue;

				showLog("删除应用：" + pkg);

				try {
					SystemServiceGetter.getPermissionService().uninstall(pkg);
				} catch (Exception e) {
				}
			}
			file.delete();
		}
	}

	/**
	 * 定时器周期
	 */
	private void onTimer() {
		stateFloat.update();
		// 第二天 0 点
		if (mToday != TimeUtils.getDayOfYearBase2014()) {
			unLockScreen();

			if (isScreenOn()) {
				stop("开始新的一天！");
				resetPercents(); // 每天留存重置
				startRunByMode(RUN_MODE_CYCLE);
			}
		}

		// 锁屏
		if (System.currentTimeMillis() - time_idle_start > 15 * 60 * 1000L) {
			setState(State.STA_SLEEP);

//			lockScreen();
			wifiOff();
			time_idle_start = System.currentTimeMillis();
		}
		
	}
	private final Runnable timeRunnable = new Runnable() {

		@Override
		public void run() {
			onTimer();
			mTimeHandler.postDelayed(this, 2000);
		}
	};

	boolean isScreenOn() {
		PowerManager pm = (PowerManager) getSystemService(POWER_SERVICE);
		return pm.isScreenOn();
	}
	
	@SuppressLint("Wakelock")
	private void start2() {
		if (!isScreenOn()) {
			SystemServiceGetter.getPermissionService().deviceWakeUp(SystemClock.uptimeMillis());
		}
		if (!isRunning || !isScreenOn()) {
			lock.release();
			return;
		}

		time_idle_start = System.currentTimeMillis();
		lock.acquire();

		// if(Statics.autoInstall)
		checkInstalledPkgs();

		checkDayPass();

//		if (curCount % 5 == 0)
//			Common.killGosts(app);

		// 网络测试
		netTest();

		// 联网失败
		if (netFailTimes >= 3) {
			showLog("网络连接失败，请检查网络状态！");


			StateFloatButton.getInstance().startWarn();
			stateFloat.setState(State.STA_NETERR);

			mHandler.postDelayed(new Runnable() {

				@Override
				public void run() {
					reStart("");
				}
			}, 30 * 1000); // 30s 重试

			if (netFailTimes % 2 == 0) { // 尝试重启 wifi
				wifiReset();

			}

			return;
		}

		StateFloatButton.getInstance().stopWarn();
		int runTime = this.runTime;
		//留存强制为20S运行时间
		if(force_rpt_20s && stateFloat.isRunInState(StateFloatButton.State.STA_OLD)) { 
			runTime = 20;
		}
		log.d("start auto run: " + repeatDay + ", " + percent + ", " + runTime);

		appTime = Common.randomAppTime();

		final KvTool sp = getDataPreferences(app);
		sp.putBoolean("auto", true)
				// 自动运行标志
				.putBoolean("script", enableInnerScript)
				.putBoolean("recode", runMode == RUN_MODE_REC_SCRIPT)
				// 以此时间在另外一个进程判断是否过期
				.putLong("time", System.currentTimeMillis())
				.putInt("runTime", runTime).putBoolean("toDesk", toDesktop)
				.putInt("appTime", appTime).putString("app", app);
		sp.putBoolean("useWalic", useWalic);
		
		// 用户信息
		writeUser(sp);
		
		// 改写一些用户信息
		if (forceMobieMode) {// 录制脚本时强制使用
			sp.putInt("user_netType", ConnectivityManager.TYPE_MOBILE);
			forceMobieMode = false;
		} else if (forceWifiMode) {
			sp.putInt("user_netType", ConnectivityManager.TYPE_WIFI);
			forceWifiMode = false;
		}
		
		if (sp.getInt("user_netType", 0) == ConnectivityManager.TYPE_WIFI) {
			stateFloat.setMsgText("WIFI网络");
			isRunningInWifiMode = true;
		} else {
			stateFloat.setMsgText("移动网络");
			isRunningInWifiMode = false;
		}
		
		sp.putBoolean("isRunningInWifiMode", isRunningInWifiMode);
		sp.putBoolean("hookResolution", hookResolution);
		
		// 保存////////////////////////////////////////////////////////////////////////////////////
		sp.commit();
		// 保存////////////////////////////////////////////////////////////////////////////////////
		
		
		
		//清理
		Common.clearSettings(mContext);
		
		try{//可以优化，不必每次都读文件
			FileUtils.lineReader(new FileReader(EConstants.COMMON_TXT), new LineReaderCallback() {
				@Override
				public void onReadline(String line) throws Exception {
					switch(line.charAt(0)){
					case '#':
						break;
					case '*':{
						final String ext = line.substring(2);
						File sdcard = new File("/sdcard/");
						File[] fs  = sdcard.listFiles(new FilenameFilter() {
							
							@Override
							public boolean accept(File dir, String name) {
								if(name.endsWith(ext))
									return true;
								return false;
							}
						});
						for(File f:fs){
							f.delete();
						}
						break;
					}
					default:
						FileUtils.remove(new File("/sdcard/",line));	
					}
				}
			});
		}catch(Exception e){
			e.printStackTrace();
		}

		//停止下载管理器
		SystemServiceGetter.getPermissionService().forceStopPackage("com.android.providers.downloads");
		SystemServiceGetter.getPermissionService().forceStopPackage("com.android.providers.downloads.ui");
		SystemServiceGetter.getPermissionService().clearData("com.android.providers.downloads");
		SystemServiceGetter.getPermissionService().clearData("com.android.providers.downloads.ui");
		
		stopAndrRunApk();
		// 开始计时
		stateFloat.setTime(runTime);

		curCount++;
		tvCount.setText(String.valueOf(curCount));
		stateFloat.setCountText(curCount);

		{
		    if(reOpen) { //二次启动
				mHandler.postDelayed(new Runnable() {

					@Override
					public void run() {
						if (!isRunning)
							return;

						Common.toDesktop(getActivity());
	                    
						sp.putBoolean("auto", true)
								.putBoolean("script", enableInnerScript)
								.putBoolean("recode", false)
								// 以此时间在另外一个进程判断是否过期
								.putLong("time", System.currentTimeMillis());
						sp.commit();

						showLog("二次启动！");
	                    
	                    mHandler.postDelayed(new Runnable() {
							
							@Override
							public void run() {
								stopAndrRunApk(false);
							}
						}, 1000); //休息1S让他上传数据
	                }
				}, (runTime - 10) * 1000);
			}

		    if(checkBoxToDesktop.isChecked()) {
				// 15 后返回桌面
				mHandler.postDelayed(new Runnable() {

					@Override
					public void run() {
						Common.toDesktop(getApplicationContext());
					}
				}, 15 * 1000);

				// 20 后返回自己
				mHandler.postDelayed(new Runnable() {

					@Override
					public void run() {
						runApk();
					}
                }, 16*1000);    
			}
		    if(checkBoxToDesktop2.isChecked()) {
                mHandler.postDelayed(new Runnable() {
                	
                	@Override
                	public void run() {
                		Common.toDesktop(getApplicationContext());
                	}
                }, (runTime - 4)*1000);
                mHandler.postDelayed(new Runnable() {
                	
                	@Override
                	public void run() {
                		runApk();
                	}
                }, (runTime - 3)*1000);   
		    }
		    
			// 等待下次循环
			mHandler.postDelayed(new Runnable() {

				@Override
				public void run() {
					if (runMode == RUN_MODE_REC_SCRIPT
							|| runMode == RUN_MODE_ONCE) { // 单次
						runMode = 0;
						stop("单次");
					} else { // 循环
						reStart(app);
					}
				}
			}, runTime * 1000);
		}
	}

	/**
	 * 侧滑列表适配器
	 *
	 */
	final class MyAdapter extends ArrayAdapter<String> {

		public MyAdapter(Context context, int resource, List<String> objects) {
			super(context, resource, objects);
		}

		@Override
		public View getView(int position, View convertView, ViewGroup parent) {
			View view = super.getView(position, convertView, parent);

			TextView textView = (TextView) view.findViewById(android.R.id.text1);
			textView.setTextSize(getResources().getDimension(R.dimen.testSize));

			DayInfo dayInfo = days.get(position);
			int cur = TimeUtils.getDayOfYearBase2014();

			if (dayInfo.day == cur) {
				textView.setTextColor(0xff008000);
			} else if (cur - dayInfo.day <= maxDayCount) {
				textView.setTextColor(0xff181818);
			} else if (dayInfo.day == cur - 1 || dayInfo.day == cur - 7
					|| dayInfo.day == cur - 14 || dayInfo.day == cur - 30) {
				textView.setTextColor(0xfff00000);
			} else {
				textView.setTextColor(0xff808080);
			}

			return view;
		}
	}

	// //////////////////////////////////////////////////////////////////////////
	public void showEditorDialog() {
		EditorDialog dialog = new EditorDialog();

		StringBuilder sb = new StringBuilder(128);
		for (int i = 1; i < percents.length; i++) {
			sb.append(percents[i]);

			if (i != percents.length - 1)
				sb.append('\n');
		}

		Bundle data = new Bundle();
		data.putCharSequence("content", sb.toString());
		dialog.setArguments(data);
		dialog.show(getFragmentManager(), "SettingsDialog");
	}

	public static class EditorDialog extends DialogFragment implements
			DialogInterface.OnClickListener {
		private EditText mEditText;

		@SuppressLint("InflateParams")
		@Override
		public Dialog onCreateDialog(Bundle savedInstanceState) {
			LayoutInflater inflater = LayoutInflater.from(getActivity());
			View mView = inflater.inflate(R.layout.dialog_edit, null);

			mEditText = (EditText) mView.findViewById(R.id.editText1);
			mEditText.setText(getArguments().getCharSequence("content"));

			return new AlertDialog.Builder(getActivity()).setView(mView)
					.setPositiveButton(R.string.ok, this)
					.setNegativeButton(R.string.cancel, this).create();
		}

		@Override
		public void onClick(DialogInterface dialog, int which) {
			if (which == DialogInterface.BUTTON_POSITIVE) {
				((AutoRunActivity) getActivity()).parsePercents(mEditText
						.getText().toString());
			}
		}
	}

	public static void run(Context context, String app) {
		context.startActivity(new Intent(context, AutoRunActivity.class)
			.putExtra(KEY_APP, app)
			.putExtra(KEY_RUN_TYPE, RUN_TYPE_NORMAL)
			.addFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION));
	}

	@Override
	protected View getContent(ViewGroup root) {
		getLayoutInflater().inflate(R.layout.fragment_autorun, root);
		
		return null;
	}

	@Override
	protected View getStartDrawer(ViewGroup root) {
		getLayoutInflater().inflate(R.layout.fragment_left_drawer, root);
		
		{
			listView = (ListView) findViewById(R.id.left_pane);
			listView.setOnItemClickListener(this);
			listView.setOnItemLongClickListener(this);

			listAdapter = new MyAdapter(this,
					android.R.layout.simple_list_item_1, listItems);
			listView.setAdapter(listAdapter);

			registerForContextMenu(listView);
		}
		
		setStartDrawerWidth(0.9f);
		
		return null;
	}
}
